import { useSyncExternalStore } from "react"
// const res = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
// const subscribe = (callback: () => void) => {
//     // 订阅
//     callback() 
//     return () => { 
//         // 取消订阅
//     }
// }

// const getSnapshot = () => {
//     return data
// }

// const res = useSyncExternalStore(subscribe, getSnapshot)

/**
 * 监听缓存变化的hooks
 * @param key 
 * @param initVal 
 * @returns 
 */
export function useStorage(key:string,initVal:any) {
    let lastStr = localStorage.getItem(key)
    let lastObj = lastStr ? JSON.parse(lastStr) : initVal
    // 触发组件更新方法， callback是api提供的回调
    function subscribe(callback:()=>void) {
            // callback调用通知组件可能需要更新，因为值如果不变，不更新
        window.addEventListener('storage',callback)

        // 返回取消订阅f方法
        return () => window.removeEventListener('storage', callback)
    }

    // getSnapshot 是返回数据的方法
    function getSnapshot() {
        // 直接返回可能导致死循环，因为每次都是对象的话，对象地址不一样
        // const data = localStorage.getItem(key)
        // return (data?JSON.parse(data):null) || initVal
        const str = localStorage.getItem(key)
        if (str === lastStr) {
            return lastObj
        }
        lastStr = str
        lastObj = str ? JSON.parse(str) : initVal
        return lastObj
    }

    // 提供外部修改缓存值
   function setVal(val:any) {
    localStorage.setItem(key,JSON.stringify(val))
    // 不同源页面会自动触发，但是同页面不会，手动触发一下
    // window.dispatchEvent(new StorageEvent('storage'))
    window.dispatchEvent(new Event('storage'))
   } 

 const res = useSyncExternalStore(subscribe, getSnapshot)

 return [res,setVal]

}


/**
 * 实时获取当前urL
 */
export function useHistory() {

    function subscribe(callback:()=>void) {
        window.addEventListener('popstate',callback)

        window.addEventListener('hashchange',callback)

        return ()=> {
            window.removeEventListener('popstate',callback)
            window.removeEventListener('hashchange',callback)
        }
    }

    function getSnapshot() {
        return window.location.href
    }

    function push(path:string) {
        window.history.pushState(null,'',path)
        // 触发更新
        window.dispatchEvent(new PopStateEvent('popstate'))
    }

    function replace(path:string) {
        window.history.replaceState(null,'',path)
        window.dispatchEvent(new PopStateEvent('popstate'))

    }

    const res = useSyncExternalStore(subscribe,getSnapshot)

    // return [res,push,replace]
    // 加as const变成元组，定好每一项类型，不然报错
    return [res, push, replace] as const
}
